package com.maychat.controller;

import com.maychat.config.AppConfig;
import com.maychat.config.Consts;
import com.maychat.controller.base.BaseController;
import com.maychat.exception.BusinessException;
import com.maychat.exception.NoAuthException;
import com.maychat.pojo.*;
import com.maychat.pojo.extended.GroupInfoWithOwnerName;
import com.maychat.service.AppUpdateService;
import com.maychat.service.CustomUserIdInfoService;
import com.maychat.service.GroupInfoService;
import com.maychat.service.UserInfoService;
import com.maychat.service.impl.RedisServiceImpl;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;

@RestController
@RequestMapping("/admin")
public class AdminController extends BaseController {

    @Autowired
    UserInfoService userInfoService;

    @Autowired
    CustomUserIdInfoService customUserIdInfoService;

    @Autowired
    GroupInfoService groupInfoService;

    @Autowired
    RedisServiceImpl redisService;

    @Autowired
    private AppConfig appConfig;

    @Autowired
    private AppUpdateService appUpdateService;

    @PostMapping("/getUsers")
    public Result getUsers(@RequestParam(defaultValue = "1") Integer page,
                           @RequestParam(defaultValue = "10") Integer pageSize,
                           @RequestBody UserInfo userInfo) throws NoAuthException, BusinessException {
        getTokenObjAndValidateAdmin();
        RowsWithTotal<UserInfo> rows = userInfoService.adminSelectUsers(userInfo, page, pageSize);
        return Result.success(rows);
    }

    @PutMapping("/updateUserStatus")
    public Result updateUserStatus(@NotNull Integer status, @NotBlank String userId) throws NoAuthException,
            BusinessException {
        getTokenObjAndValidateAdmin();
        userInfoService.updateUserStatusById(userId, status);
        return Result.success();
    }

    @PostMapping("/kick")
    public Result forceOffline(@NotBlank String userId) throws NoAuthException, BusinessException {
        UserInfoToken tokenObj = getTokenObjAndValidateAdmin();
        if (userId.equals(tokenObj.getUserId()))
            return Result.error("BAN自己可还行");
        userInfoService.kick(userId);
        return Result.success();
    }

    //
    @PostMapping("/getCustoms")
    public Result getCustoms(@RequestParam(defaultValue = "1") Integer page,
                             @RequestParam(defaultValue = "10") Integer pageSize,
                             @RequestBody CustomUserIdInfo custom) throws NoAuthException, BusinessException {
        getTokenObjAndValidateAdmin();
        RowsWithTotal<CustomUserIdInfo> rows = customUserIdInfoService.selectCondByPage(custom, page, pageSize);
        return Result.success(rows);
    }

    @PostMapping("/saveCustom")
    public Result saveCustom(CustomUserIdInfo custom) throws NoAuthException, BusinessException {
        getTokenObjAndValidateAdmin();
        customUserIdInfoService.saveCustom(custom);
        return Result.success();
    }

    @DeleteMapping("/delCustom")
    public Result delCustom(@NotNull Integer id) throws NoAuthException, BusinessException {
        getTokenObjAndValidateAdmin();
        customUserIdInfoService.delById(id);
        return Result.success();
    }
    //

    @PostMapping("/getGroups")
    public Result getGroups(@RequestParam(defaultValue = "1") Integer page,
                            @RequestParam(defaultValue = "10") Integer pageSize,
                            @RequestBody GroupInfo groupInfo) throws NoAuthException, BusinessException {
        getTokenObjAndValidateAdmin();
        RowsWithTotal<GroupInfoWithOwnerName> rows = groupInfoService.selectWithOwnerNameCondByPage(groupInfo, page,
                pageSize);
        return Result.success(rows);
    }

    @DeleteMapping("/dissolveGroup")
    public Result dissolveGroup(@NotNull String groupId) throws NoAuthException, BusinessException {
        getTokenObjAndValidateAdmin();
        GroupInfo dbInfo = groupInfoService.selectGroupInfoById(groupId);
        groupInfoService.dissolveGroup(groupId, dbInfo.getGroupOwnerId());
        return Result.success();
    }

    //
    @PutMapping("/updateOptions")
    public Result updateOptions(@NotNull MayChatSystemOptions options, MultipartFile robotSmall, MultipartFile robotFull) throws NoAuthException, BusinessException, IOException {
        getTokenObjAndValidateAdmin();
        if (robotSmall != null && robotFull != null) {
            String fileFolder = appConfig.getProjectFolder() + Consts.FOLDER_FILE_AVATAR;
            File file = new File(fileFolder);
            if (!file.exists()) file.mkdirs();
            String avatarBasePath = fileFolder + "/" + Consts.ROBOT_UID;
            robotSmall.transferTo(new File(avatarBasePath + Consts.IMAGE_SMALL_SUFFIX));
            robotFull.transferTo(new File(avatarBasePath + Consts.IMAGE_SUFFIX));
        }
        redisService.updateSystemOptions(options);
        return Result.success();
    }

    //
    @PostMapping("/getUpdates")
    public Result getUpdates(@RequestParam(defaultValue = "1") Integer page,
                             @RequestParam(defaultValue = "10") Integer pageSize,
                             @RequestBody AppUpdate appUpdate
    ) throws NoAuthException, BusinessException {
        getTokenObjAndValidateAdmin();
        RowsWithTotal<AppUpdate> rows = appUpdateService.selectCondByPage(appUpdate, page, pageSize);
        return Result.success(rows);
    }

    @PostMapping("/saveUpdate")
    public Result saveUpdate(@NotNull AppUpdate appUpdate, MultipartFile file) throws NoAuthException, BusinessException, IOException {
        getTokenObjAndValidateAdmin();
        appUpdateService.saveUpdate(appUpdate, file);
        return Result.success();
    }

    @DeleteMapping("/delUpdate")
    public Result delUpdate(@NotNull Integer id) throws NoAuthException, BusinessException {
        getTokenObjAndValidateAdmin();
        appUpdateService.delById(id);
        return Result.success();
    }

    @PutMapping("/releaseUpdate")
    public Result releaseUpdate(@NotNull Integer id, @NotNull Integer status, @NotNull String grayscaleId) throws NoAuthException,
            BusinessException {
        getTokenObjAndValidateAdmin();
        appUpdateService.releaseUpdate(id, status, grayscaleId);
        return Result.success();
    }
}
